
#include "zepplist.h"
#include <stdio.h>
#include <string.h>
#include <unistd.h>

struct list_head *create_list_head() {
    struct list_head *list = (struct list_head *)calloc(1, sizeof(struct list_head));
    return list;
}

void list_node_data_alloc(struct list_node *node) {
    node->datas = (Datatype *)calloc(Datasize, sizeof(Datatype));
}

void init_list_head(struct list_head *list) {
    if (list == NULL)
        return;
    list->nil = (struct list_node *)calloc(1, sizeof(struct list_node));
    list->head = list->nil;
    list->tail = list->nil;

    list->nil->next = list->nil;
    list->nil->prev = list->nil;
}

struct list_node *create_list_node() {
    struct list_node *node = (struct list_node *)calloc(1, sizeof(struct list_node));
    list_node_data_alloc(node);
    return node;
}

void destroy_list(struct list_head *list) {
    struct list_node *pos = list->head;
    struct list_node *pos_next = NULL;
    while (pos != list->nil) {
        pos_next = pos->next;
        list_remove(list, pos);
        pos = pos_next;
    }
    destroy_list_head(list);
}

void destroy_list_head(struct list_head *list) {
    free(list->nil);
    free(list);
}

void list_node_data_destroy(struct list_node *node) {
    free(node->datas);
}

void destroy_list_node(struct list_node *node) {
    list_node_data_destroy(node);
    free(node);
}


void insert_list_after(struct list_head *list, struct list_node *base, struct list_node *after) {
    after->next = base->next;
    after->prev = base;

    after->next->prev = after;

    base->next = after;

    list->size++;
}



void insert_list_before(struct list_head *list, struct list_node *base, struct list_node *before) {
    before->next = base;
    before->prev = base->prev;

    before->prev->next = before;

    base->prev = before;

    list->size++;
}

void insert_list_head(struct list_head *list, struct list_node *node) {
    insert_list_before(list, list->head, node);
    list->head = node;
    if (list->tail == list->nil)
        list->tail = node;
}

void insert_list_tail(struct list_head *list, struct list_node *node) {
    insert_list_after(list, list->tail, node);
    list->tail = node;
    if (list->head == list->nil)
        list->head = node;
}

void list_remove(struct list_head *list, struct list_node *node) {
    if (node == list->head) {
        list->head = node->next;
    }
    if (node == list->tail) {
        list->tail = node->prev;
    }
    struct list_node *next = node->next;
    next->prev = node->prev;
    node->prev->next = next;
    destroy_list_node(node);
    list->size--;
}

// 将[first, last) 移动到pos前
static void transfer(struct list_head *list,
  struct list_node *pos, struct list_node *first, struct list_node *last) {
  if (pos != last) {
    last->prev->next = pos;
    first->prev->next = last;
    pos->prev->next = first;

    struct list_node *tmp = pos->prev;
    pos->prev = last->prev;
    last->prev = first->prev;
    first->prev = tmp;
  }
}

void list_swap_node(struct list_head *list, struct list_node *a, struct list_node *b) {
#if 1

    if (a == b || a == list->nil || b == list->nil) {
        return;  // 如果 a 和 b 相同或为 nil，直接返回
    }

    // 首先保存 a 和 b 的前驱和后继节点
    struct list_node *a_prev = a->prev;
    struct list_node *a_next = a->next;
    struct list_node *b_prev = b->prev;
    struct list_node *b_next = b->next;

    // 如果 a 和 b 是相邻节点，需要额外处理
    if (a_next == b) {
        // a 在 b 前面
        a->next = b_next;
        a->prev = b;
        b->next = a;
        b->prev = a_prev;
    } else if (b_next == a) {
        // b 在 a 前面
        // b->next = a_next;
        // b->prev = a;
        // a->next = b;
        // a->prev = b_prev;
        list_swap_node(list, b, a);
    } else {
        // 如果 a 和 b 不相邻，直接交换它们的前驱和后继
        a->next = b_next;
        a->prev = b_prev;
        b->next = a_next;
        b->prev = a_prev;
    }

    // 更新 a 和 b 原先的前驱和后继节点的指针
    if (a->prev != list->nil) {
        a->prev->next = a;
    } else {
        list->head = a;  // 如果 a 成为了头节点
    }

    if (a->next != list->nil) {
        a->next->prev = a;
    } else {
        list->tail = a;  // 如果 a 成为了尾节点
    }

    if (b->prev != list->nil) {
        b->prev->next = b;
    } else {
        list->head = b;  // 如果 b 成为了头节点
    }

    if (b->next != list->nil) {
        b->next->prev = b;
    } else {
        list->tail = b;  // 如果 b 成为了尾节点
    }
#else
    // FIXME: head and tail position error
  struct list_node *a_next = a->next;
  if (a_next == b) {
    // a, b相邻
    transfer(list, a, b, b->next);
    list->head = list->nil->next;
    list->tail = list->nil->prev;
    return;
  }
  //  3 -> 4 -> a -> 5 -> 6 -> b -> 7 -> 8
  transfer(list, b, a, a_next); // ..4 -> 5 -> 6 -> a -> b -> 7..
  return list_swap_node(list, a, b); // 此时a，b相邻
#endif
}

void list_swap_data(struct list_head *list, Datatype *a, Datatype *b) {
    printf("a: %d, b: %d\n", *a, *b);
    // Datatype *temp_data = a;
    // a = b;
    // b = temp_data;

    Datatype *temp_data = (Datatype *)malloc(sizeof(Datatype));
    memcpy(temp_data, a, sizeof(Datatype));
    memcpy(a, b, sizeof(Datatype));
    memcpy(b, temp_data, sizeof(Datatype));

    printf("a: %d, b: %d\n", *a, *b);
}

struct list_node *get_index_block(struct list_head *list, int index) {
    struct list_node *pos = list->head;
    while (index -- && pos ->next) {
        pos = pos->next;
    }
    return pos;
}

Datatype *get_index(struct list_head *list, int index) {
    int blk_idx = index / Datasize;
    struct list_node *blk = get_index_block(list, blk_idx);
    return blk->datas + (index % Datasize);
}